﻿using System;
using System.ComponentModel.Composition;
using Cubicle.Core.Interfaces;

namespace Cubicle.Core.Processors.Parameter
{
    [Export("Cubicle.Processors.Parameter.ArrayParameterResolver", typeof(IProcessor<ParameterRequest>))]
    [ExportMetadata("Name", "ArrayParameterResolver")]
    [ExportMetadata("Description", "Resolves a parameter to a strongly typed array.")]
    public class ArrayParameterResolver : ConditionalProcessor<ParameterRequest>
    {
        [Import]
        private ParameterProcessor _parameterProcessor;

        #region Overrides of Processor<ParameterRequest>

        public override bool Condition(ParameterRequest request)
        {
            return request.SourceType.IsArray
                   && request.SourceType.GetArrayRank() == 1
                   && request.TargetType.IsArray
                   && request.TargetType.GetArrayRank() == 1;
        }

        public override ParameterRequest ConditionalProcess(ParameterRequest request)
        {
            var valueArr = request.Source as Array;
            var elemType = request.TargetType.GetElementType();
            var result = Array.CreateInstance(elemType, valueArr.Length);

            // We cannot use a ParameterArrayProcessor here because it will create object[] instead of
            // the corret type

            // Resolve individually
            for (int i = 0; i < valueArr.Length; i++)
            {
                var parRequest = new ParameterRequest(elemType, valueArr.GetValue(i));
                _parameterProcessor.Process(parRequest);
                result.SetValue(parRequest.Result, i);
            }

            request.Complete(result);
            return request;
        }

        #endregion
    }
}